#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    this->setGeometry(0, 0, 800, 480);
    udpSocket = new QUdpSocket(this);

    pushButton[0] = new QPushButton();
    pushButton[0]->setText("绑定端口");
    pushButton[1] = new QPushButton();
    pushButton[1]->setText("解绑端口");
    pushButton[1]->setEnabled(false);
    pushButton[2] = new QPushButton();
    pushButton[2]->setText("清空文本");
    pushButton[3] = new QPushButton();
    pushButton[3]->setText("发送消息");
    pushButton[3]->setEnabled(false);
    pushButton[4] = new QPushButton();
    pushButton[4]->setText("广播消息");
    pushButton[4]->setEnabled(false);

    label[0] = new QLabel();
    label[0]->setText("目标IP:");
    label[0]->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    label[1] = new QLabel();
    label[1]->setText("目标PORT:");
    label[1]->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
    label[2] = new QLabel();
    label[2]->setText("绑定PORT:");
    label[2]->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

    textBrowser = new QTextBrowser();

    comboBox = new QComboBox();/* 显示本地IP */
    spinBox[0] = new QSpinBox();
    spinBox[0]->setRange(10000, 99999);
    spinBox[1] = new QSpinBox();
    spinBox[1]->setRange(10000, 99999);

    lineEdit = new QLineEdit();/* 文本输入框 */
    lineEdit->setText("你好！");

    hWidget[0] = new QWidget();
    hBoxLayout[0] = new QHBoxLayout();
    hBoxLayout[0]->addWidget(label[0]);
    hBoxLayout[0]->addWidget(comboBox);
    hBoxLayout[0]->addWidget(label[1]);
    hBoxLayout[0]->addWidget(spinBox[0]);
    hBoxLayout[0]->addWidget(label[2]);
    hBoxLayout[0]->addWidget(spinBox[1]);
    hWidget[0]->setLayout(hBoxLayout[0]);

    hWidget[1] = new QWidget();
    hBoxLayout[1] = new QHBoxLayout();
    hBoxLayout[1]->addWidget(pushButton[0]);
    hBoxLayout[1]->addWidget(pushButton[1]);
    hBoxLayout[1]->addWidget(pushButton[2]);
    hWidget[1]->setLayout(hBoxLayout[1]);

    hWidget[2] = new QWidget();
    hBoxLayout[2] = new QHBoxLayout();
    hBoxLayout[2]->addWidget(lineEdit);
    hBoxLayout[2]->addWidget(pushButton[3]);
    hBoxLayout[2]->addWidget(pushButton[4]);
    hWidget[2]->setLayout(hBoxLayout[2]);

    vWidget = new QWidget();
    vBoxLayout = new QVBoxLayout();
    vBoxLayout->addWidget(textBrowser);
    vBoxLayout->addWidget(hWidget[0]);
    vBoxLayout->addWidget(hWidget[1]);
    vBoxLayout->addWidget(hWidget[2]);
    vWidget->setLayout(vBoxLayout);

    setCentralWidget(vWidget);

    getLocalHostIp();

    connect(pushButton[0], &QPushButton::clicked, this, &MainWindow::bindPort);
    connect(pushButton[1], &QPushButton::clicked, this, &MainWindow::unbindPort);
    connect(pushButton[2], &QPushButton::clicked, this, &MainWindow::clearTestBrowser);
    connect(pushButton[3], &QPushButton::clicked, this, &MainWindow::sendMessages);
    connect(pushButton[4], &QPushButton::clicked, this, &MainWindow::sendBroadcastMessages);
    connect(udpSocket, &QUdpSocket::readyRead, this, &MainWindow::recvMessages);
    connect(udpSocket, &QUdpSocket::stateChanged, this, &MainWindow::socketStateChange);
}

MainWindow::~MainWindow()
{
    delete udpSocket;
}

void MainWindow::getLocalHostIp()
{
    QList<QNetworkInterface> list = QNetworkInterface::allInterfaces();
    foreach (auto& interface, list) {
        QList<QNetworkAddressEntry> entryList = interface.addressEntries();
        foreach (auto& entry, entryList) {
            if (entry.ip().protocol() ==QAbstractSocket::IPv4Protocol) {
                IPList << entry.ip();
                comboBox->addItem(entry.ip().toString());
            }
        }
    }
}

void MainWindow::bindPort()
{
    quint16 port = static_cast<quint16>(spinBox[0]->value());
    if (udpSocket->state() != QAbstractSocket::UnconnectedState) {
        udpSocket->close();
    }
    bool bindRet = udpSocket->bind(static_cast<quint16>(spinBox[1]->value()));
    if (bindRet) {
        textBrowser->append("已经成功绑定端口:" + QString::number(port));
        pushButton[0]->setEnabled(false);
        pushButton[1]->setEnabled(true);
        pushButton[3]->setEnabled(true);
        pushButton[4]->setEnabled(true);
        spinBox[1]->setEnabled(false);
    }
}

void MainWindow::unbindPort()
{
    udpSocket->abort();/* 解绑，不在监听 */

    pushButton[0]->setEnabled(true);
    pushButton[1]->setEnabled(false);
    pushButton[3]->setEnabled(false);
    pushButton[4]->setEnabled(false);
    spinBox[1]->setEnabled(true);
}

void MainWindow::clearTestBrowser()
{
    textBrowser->clear();
}

void MainWindow::recvMessages()
{
    QHostAddress peerAddress;
    quint16 peerPort;

    while (udpSocket->hasPendingDatagrams()) {
        QByteArray datagram;

        datagram.resize(static_cast<int>(udpSocket->pendingDatagramSize()));
        udpSocket->readDatagram(datagram.data(), datagram.size(), &peerAddress, &peerPort);
        QString str = datagram.data();

        textBrowser->append("接受来自" + peerAddress.toString() + ":" + QString::number(peerPort) + str);
    }
}

void MainWindow::sendMessages()
{
    textBrowser->append("发送:" + lineEdit->text());

    QByteArray data = lineEdit->text().toUtf8();

    QHostAddress peerAddress = IPList[comboBox->currentIndex()];
    quint16 peerPort = static_cast<quint16>(spinBox[1]->value());

    udpSocket->writeDatagram(data, peerAddress, peerPort);
}

void MainWindow::sendBroadcastMessages()
{
    textBrowser->append("发送:" + lineEdit->text());

    QByteArray data = lineEdit->text().toUtf8();

    QHostAddress peerAddress = QHostAddress::Broadcast;
    quint16 peerPort = static_cast<quint16>(spinBox[1]->text().toInt());

    udpSocket->writeDatagram(data, peerAddress, peerPort);
}

void MainWindow::socketStateChange(QAbstractSocket::SocketState state)
{
    qDebug() << state << endl;
}
